home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
cobalts.arc
/
COBALTS.C
< prev
next >
Wrap
Text File
|
1990-09-03
|
17KB
|
523 lines
/* Mix Power C 2.0 Large Memory Model */
/* uncomment the next line to use with MICROSOFT */
/* #define MICROSOFT */
/* this program uses a CGA emulation routine for the HERC to allow */
/* HERCULES Graphics card users to view CGA compatible graphics. */
/* =================[ CGA to HERCULES conversion ]===============*/
/* Comparison Ratio: pixels size */
/* the hercules display is 720 = 90 bytes wide */
/* 348 = 87 "half-bytes" deep */
/* the cga HI_RES display is 640 = 80 bytes wide */
/* 200 = 50 "half-bytes" deep */
/* horizontal transformation reduction 8:9 = */
/* 640 = 80 bytes literal */
/* vertical transformation ratio 3:2 = */
/* 300 = 50 "half-bytes" deep */
/* A slightly (11%) smaller but reasonably accurate facsimile */
/* of bit images ported from the cga may be displayed on the herc*/
/* by applying the horizontal resolution transformation factor */
/* vertically then writing an extra scanline on every odd line */
/* relative to CGA coordinates. This is done as a "filler" and */
/* will widen horizontal lines in lineart reproductions if they */
/* fall on the (interleaf) filler line. Also, the aspect ratio */
/* is minimally (4%) reduced in the yaxis. */
/* there are 2-significant advantages to this algorithm. */
/* 1. speed of execution due to integer arithmetic and the use */
/* of the modulus operator and simple logic. */
/* 2. greater image clarity due to maintaining true pixel ratio */
/* in the x axis and a single-interleaf repeat in the y axis */
/* thereby preserving a regular transformation matrix ratio. */
/*===============================================================*/
/* Made in Canada by bill buckels 1990
a demonstration of embedded graphics and a virtual screen.
1. we use all our own routines. These are not from a text book,
nor from someone's handy toolkit.
2. Anyone wishing to use these routines to produce binary code may
do so without fee or royalty (although I would not return a
registration fee if received) and I would appreciate that no fee
be charged if you give these to another software engineer.
*/
#include <stdio.h>
#include <fcntl.h>
#include <conio.h>
#include <stdlib.h>
#include <io.h>
#include <dos.h>
#include <bios.h>
#include <string.h>
#include <malloc.h>
#ifdef MICROSOFT
#define biosequip _bios_equiplist
#define MK_FP(seg,off) ((char far *)(((long)(seg) << 16) | (off)))
#endif
/* palettes */
#define GRY 0
#define CMW 1
/* screen modes */
#define TEXT 3
#define MED_RES 4
#define HI_RES 6
#define HERCULES 99
/* default adapter */
int ADAPTER=MED_RES;
#define FRAMEBUFFER 0xb800
#define HERCTEXT 0
#define HERCGRAPH 1
int HERCLEAF[4]={0x0000,0x2000,0x4000,0x6000};
int CGALEAF[2]={0,8192};
#define HERCLINE 90
#define CGALINE 80
/* we declare the screen buffer globally and allocate the memory */
/* during initialization.*/
char far *crt;
/* The Image Descriptor Integer Array precedes the Character Array.*/
/* Descriptor Fields are: 1. Length of Character Array. */
/* 2. Width of Graphic in BYTES. */
/* 3. Height of Graphic in BYTES.*/
extern long int RUSS_SIZE[3];
extern unsigned char far RUSS[];
/* we declare the screen buffer globally and allocate the memory */
/* during initialization.*/
unsigned char far *screenbuffer[2];
long screenlength;
long screensize;
long screenwidth;
void FREE_BUFF(void)
{
_ffree(screenbuffer[0]);
_ffree(screenbuffer[1]);
}
long int topline=0l;
long int sideline=0l;
/* this is the pointer to the beginning of the screenbuffer */
long int topstop;
#define VIEWPORT 200
int STUFF_BUFF()
{
screenlength= RUSS_SIZE[2];
screenwidth= RUSS_SIZE[1];
/* break point for the 64k buffer tanks */
/* break on even boundaries */
screensize= (64000l/screenwidth)*screenwidth;
topstop = screenlength-VIEWPORT;
/* arbitary mallocation of a large block */
screenbuffer[0] = _fmalloc(64000l);
screenbuffer[1] = _fmalloc(64000l);
memset(screenbuffer[0],0x00,64000l);
memset(screenbuffer[1],0x00,64000l);
crt=MK_FP(FRAMEBUFFER,0x0000);
return 0;
}
int memoryload()
{
unsigned int packet;
unsigned char byte,bytecount;
long int wordcount=0, target=RUSS_SIZE[0],byteoff=0l;
do{ bytecount=1; /* start with a seed count */
byte=RUSS[wordcount];
wordcount++;
/* check to see if its raw */
if(0xC0 == (0xC0 &byte)){ /* if its not, run encoded */
bytecount= 0x3f &byte;
byte=RUSS[wordcount];
wordcount++;
}
for(packet=0;packet<bytecount;packet++){
if(byteoff<screensize)screenbuffer[0][byteoff]=byte;
else screenbuffer[1][byteoff-screensize]=byte;
byteoff++;
}
}while(wordcount<target);
return(0);
}
void HERC_CLS(void)
{
memset(crt,0,32767);
}
/* 6485 controller mode data */
char HERC_DAT[2][12] = { { 0x61, 0x50, 0x52, 0x0f, 0x19, 0x06,
0x19, 0x19, 0x02, 0x0d, 0x0b, 0x0c },
{ 0x35, 0x2d, 0x2e, 0x07, 0x5b, 0x02,
0x57, 0x57, 0x02, 0x03, 0x00 ,0x00 } };
void HERC_MODE(int ctrlmode)
{
unsigned int reg,ctrl;
ctrl = (ctrlmode) ? 0x82 : 0x20;
outp(0x3bf,3) ; /* allow graphics enable page 1 */
outp(0x3b8,ctrl) ; /* disable video and set mode */
for (reg = 0; reg <= 11; reg++) { /* program the crt parameters */
outp(0x3b4,reg) ;
outp(0x3b5,HERC_DAT[ctrlmode][reg]);
}
outp(0x3b8,ctrl+8) ; /* re-enable the video */
}
int setcrtmode(unsigned char _CRT_MODE)
{
union REGS rin,rout;
if ((biosequip() & 0x30) == 0x30){
ADAPTER=HERCULES ;
if(_CRT_MODE == TEXT){
HERC_CLS() ;
HERC_MODE(HERCTEXT) ;
}
else{HERC_MODE(HERCGRAPH) ;
HERC_CLS() ;
}
return (0) ;
}
rin.h.ah = 0;
rin.h.al = _CRT_MODE;
int86(0x10,&rin,&rout);
return 0;
}
int colorset(background, palette)
unsigned char background, palette;
{
union REGS rin,rout;
if(ADAPTER==HERCULES || ADAPTER==HI_RES) return 0;
rin.h.ah = 11;
rin.h.bh = 0;
rin.h.bl = background;
int86(0x10,&rin,&rout);
rin.h.bh = 1;
rin.h.bl = palette;
int86(0x10,&rin,&rout);
return 0;
}
int cload()
{
unsigned int y,inset=((HERCLINE*6)+5);
long offset=(topline*screenwidth)+sideline;
if(ADAPTER==HERCULES){
for(y=0;y!=300;y++){
if(offset<screensize)
memcpy((crt+HERCLEAF[y%4]+inset),(screenbuffer[0]+offset),CGALINE);
else
memcpy((crt+HERCLEAF[y%4]+inset),(screenbuffer[1]+(offset-screensize)),
CGALINE);
if(y%4==3)inset+=HERCLINE;
if(y%3!=2)offset+=screenwidth;
}
return(0);
}
inset = 0;
for(y=0;y<200;){
if(offset<screensize)
memcpy((crt+CGALEAF[0]+inset),(screenbuffer[0]+offset),CGALINE);
else
memcpy((crt+CGALEAF[0]+inset),(screenbuffer[1]+(offset-screensize)),
CGALINE);
offset+=screenwidth;y++;
if(offset<screensize)
memcpy((crt+CGALEAF[1]+inset),(screenbuffer[0]+offset),CGALINE);
else
memcpy((crt+CGALEAF[1]+inset),(screenbuffer[1]+(offset-screensize)),
CGALINE);
offset+=screenwidth;
inset+=CGALINE;
y++;
}
return(0);
}
#define ESCKEY '\x1b' /* character generated by the Esc key */
#define FUNCKEY '\x00' /* first character generated by function keys */
#define HOMEKEY 'G' /* second character generated by Home key */
#define ENDKEY 'O' /* second character generated by End key */
#define UPARROW 'H' /* second character generated by up-arrow key */
#define DOWNARROW 'P' /* second character generated by down-arrow key */
#define LEFTARROW 'K' /* second character generated by left-arrow key */
#define RIGHTARROW 'M' /* second character generated by right-arrow key */
#define PGUP 'I' /* second character generated by page up key */
#define PGDOWN 'Q' /* second character generated by page down key */
/* colors */
#define BLACK 0
#define BLUE 1
#define GREEN 2
#define CYAN 3
#define RED 4
#define MAGENTA 5
#define BROWN 6
#define WHITE 7
#define BWHITE 15
#define BBLUE 9
#define INTENSE 16
/* Mix provide a sound function with their library */
/* as do turbo but Microsoft (& Aztec) don't. */
#define TIMEOUT 0x2c00
int sounds(freq,tlen)
int freq; /* freq of sound in Hertz */
int tlen; /* duration of sound 18.2 ticks per second */
{
union REGS inregs,outregs;
unsigned frdiv = 1331000L/freq; /* timer divisor */
int seed,hiseed,hold=0,setting;
outp(0x43,0xB6) ; /* write timer mode register */
outp(0x42,frdiv & 0x00FF); /* write divisor LSB */
outp(0x42,frdiv >> 8); /* write divisor MSB */
setting= inp(0x61); /* get current port B setting */
outp(0x61,setting | 0x03); /* turn speaker on */
if(tlen>0){
tlen=((tlen*1000)/182); /* convert from 18.2 ticks to 100ths */
inregs.x.ax= TIMEOUT;
int86(0x21,&inregs,&outregs);
seed=(outregs.x.dx)&0xff;
while(hold<tlen)
{
inregs.x.ax = TIMEOUT;
int86(0x21,&inregs,&outregs);
if(seed!=(outregs.x.dx&0xff))
{
hiseed= (outregs.x.dx)&0xff;
if(hiseed<seed)hiseed+=100;
hold+=(hiseed-seed);
seed =(outregs.x.dx)&0xff;
}
}
}
outp(0x61,setting);
/* restore port B setting */
return;
}
extern int ENTRTAN[];
/* musical array created from file ENTRTAN.SND */
/* array structure is frequency,duration */
int enterfreq=0, enterdur=1;
char entertain()
{
while(!kbhit())
{
sounds(ENTRTAN[enterfreq],ENTRTAN[enterdur]);
enterfreq+=2 ; enterdur+=2;
if (ENTRTAN[enterfreq] == -1)return 27;
}
return 0;
}
char *lineby[]={
"┌─────────────────────────────────────────────┐",
"│ Compliments of Teacher's Choice Productions │",
"│ written and produced by Bill Buckels │",
"│ │",
"│ Hotkeys are The Cursor Arrows │",
"│ Page Up and Down , Home and End │",
"│ Press \"C\" to Toggle Palettes │",
"│ │",
"│ Press Escape To Exit When Done │",
"└─────────────────────────────────────────────┘",
"",
"One Moment Please...",
NULL};
main()
{
char c=32;
int i=0;
int background=BLUE ;
int palette =CMW ;
long int temp;
while(strcmpi(lineby[i],NULL)!=0){printf("%s\n",lineby[i]);i++;}
STUFF_BUFF();
/* load the buffer */
memoryload();
setcrtmode(ADAPTER); /* initialize video */
colorset(background,palette);
/* load into the middle of the screen */
temp=(screenlength-200l)/2;
if(temp>0)topline=temp;
temp=(screenwidth-80l)/2;
if(temp>0)sideline=temp;
cload();
/* loop until an escape key is pressed */
while(c!=ESCKEY)
{
if(kbhit())c=getch();
else if(entertain()==ESCKEY)c=ESCKEY;
if(c!=ESCKEY)
{
/* color change option */
if(c=='c'|| c=='C'){
palette++;
if(palette>CMW){
background++;
palette=GRY ;
if(background>31)
background=BLACK;
}
colorset(background,palette);
}
if(c==FUNCKEY){ /* if its a function key */
c=getch(); /* get second character. */
switch(c)
{
case UPARROW:
if(topline<1)break;
if(topline>0)topline-=2;
else topline=0;
cload();
break;
case DOWNARROW:
if(topline==topstop)break;
if(topline<topstop)topline+=2;
else topline=topstop;
cload();
break;
case PGUP:
if(topline<1)break;
if(topline>199)topline-=200;
else topline=0;
memset(crt,0x00,0x4000);
cload();
break;
case PGDOWN:
if(topline==topstop)break;
topline+=200;
if(topline>topstop)topline=topstop;
memset(crt,0x00,0x4000);
cload();
break;
case HOMEKEY:
if(topline<1)break;
topline=0;
memset(crt,0x00,0x4000);
cload();
break;
case ENDKEY:
if(topline==topstop)break;
topline=topstop;
memset(crt,0x00,0x4000);
cload();
break;
case LEFTARROW:
if(sideline<1)break;
sideline--;
cload();
break;
case RIGHTARROW:
if(sideline<(screenwidth-CGALINE)){
sideline++;
cload();
}
break;
default : break;
}
}
}
}
FREE_BUFF();
setcrtmode(TEXT);
printf("Cya on the \"Programmer's Forum..\"\n");
exit(0);
}